import 'dart:math';

import 'package:flame/components.dart';
import 'package:flame/events.dart';
import 'package:flame/extensions.dart';
import 'package:flame/text.dart';
import 'package:flutter/material.dart' show Colors, FontWeight;
import 'package:flutter_flame/bloc/FlameBlocWorld.dart';
import 'package:flutter_flame/bloc/game_bloc/GameEvent.dart';
import 'package:flutter_flame/routes/RouteGame.dart';
import 'package:flutter_flame/worlds/game/components/Shovel/Shovel.dart';
import 'package:flutter_flame/worlds/game/components/plants/Cactus.dart';
import 'package:flutter_flame/worlds/game/components/seedChooserBank/SeedPacket.dart';

import '../../bloc/game_bloc/GameBloc.dart';
import '../../bloc/game_bloc/GameState.dart';
import '../../config/AssetsName.dart';
import '../../config/GameColors.dart';
import '../../config/GameConfig.dart';
import 'audio/SoundManager.dart';
import 'components/plants/Cabbagepult.dart';
import 'components/plants/PeaShooter.dart';
import 'entity/PlantEntity.dart';
import 'components/LawnCell.dart';
import 'components/BodyShadow.dart';
import 'components/Sunflower.dart';
import 'components/stage/BasicStage.dart';
import 'components/ZombiePool.dart';
import 'components/DragShadow.dart';

class GameWorld extends FlameBlocWorld<GameBloc, GameStatesState>
    with
        HasCollisionDetection,
        GameConfig,
        HasGameReference<RouterGame>,
        PointerMoveCallbacks {
  static String routeName = "pvzGame"; // 路由
  DragShadow? plantDragShadow; // 拖动种植的阴影
  TimerComponent? zombieGenerateTimer; // 僵尸生成计时器
  ZombiePool zombiePool = ZombiePool(); // 僵尸池（复用创建的对象）
  TimerComponent? zombiesTimer; // 僵尸波次生成
  DragShadow? shovelDragShadow; // 铲子的阴影
  bool selectShovel = false; // 是否选中铲子

  GameWorld(super.bloc);

  @override
  Future<void> onLoad() async {
    SoundManager().initMusic();
    SoundManager().initChooseSeeds();
    add(BasicStage(AssetsName.stageDay, onCompleted: readyForFight));
  }

  // 调试信息
  @override
  bool get debugMode => false;

  List<LawnCell> get lawnCells => children.whereType<LawnCell>().toList();

  // 铺上5*9的草坪
  Future<void> _initLawnGrid() async {
    for (int row = 0; row < rows; row++) {
      for (int col = 0; col < cols; col++) {
        add(LawnCell(row, col));
      }
    }
  }

  // 僵尸生成
  TimerComponent _spawnZombies() {
    final period = bloc.state.zombiePeriods[bloc.state.zombieTimes];
    return TimerComponent(
      period: period,
      repeat: true,
      onTick: () async {
        int row = Random().nextInt(rows);
        final zombie = zombiePool.getZombie(row);
        add(zombie);
        await zombie.loaded;
        await zombie.reset(row);
        zombie.bodyShadow = BodyShadow.following(
          AssetsName.spriteShadow,
          targetEntity: zombie,
        );
        add(zombie.bodyShadow);
      },
    );
  }

  // 游戏结束
  void gameOver() {
    if (bloc.state.isGameOver) return;
    bloc.add(GameOverEvent());
    SoundManager().stop();
    SoundManager().playBrainAte();
    add(
      TextComponent(
        text: '你的🧠被炫掉了',
        position: game.size / 2,
        anchor: Anchor.center,
        priority: menuPriority,
        textRenderer: TextPaint(
          style: TextStyle(
            fontSize: 60,
            color: Colors.red,
            fontWeight: FontWeight.bold,
          ),
        ),
      )..loaded,
    );
    Future.delayed(Duration(milliseconds: 100), () {
      game.pauseEngine();
    });
  }

  // 放置植物
  void tryPlacePlant(LawnCell cell, SeedPacket seedPacket) {
    // 放置失败
    if (cell.plant != null ||
        bloc.state.sunlight < bloc.state.selectedPlant!.costSunlight) {
      return;
    }
    seedPacket.startCoolDown(); // 植物进入冷却
    SoundManager().playPlant();
    bloc.add(CostSunlightEvent()); // 扣除阳光
    // 创建植物并添加到游戏
    cell.plant = switch (bloc.state.selectedPlant!.plantEntity) {
      PlantEntity.sunflower => Sunflower(cell, maxHp: sunflowerHp),
      PlantEntity.peashooter => PeaShooter(cell: cell),
      PlantEntity.blover => throw UnimplementedError(),
      PlantEntity.cabbagepult => Cabbagepult(cell: cell),
      PlantEntity.cactus => Cactus(cell: cell),
      PlantEntity.cattail => throw UnimplementedError(),
      PlantEntity.caltrop => throw UnimplementedError(),
      PlantEntity.cherryBomb => throw UnimplementedError(),
      PlantEntity.chomper => throw UnimplementedError(),
      PlantEntity.cobCannon => throw UnimplementedError(),
      PlantEntity.coffeeBean => throw UnimplementedError(),
    };

    // 添加植物阴影
    cell.plant!.loaded.then((_) {
      cell.plant?.bodyShadow = BodyShadow(
        AssetsName.spriteShadow,
        bodySize: cell.size,
        bodyPosition: cell.position,
      );
      add(cell.plant!.bodyShadow);
    });
    add(cell.plant!);
  }

  // 生成僵尸
  void _generateZombies() {
    zombiesTimer = TimerComponent(
      period: zombieGeneratePeriod,
      repeat: true,
      onTick: () {
        zombieGenerateTimer?.removeFromParent();
        zombieGenerateTimer = _spawnZombies();
        bloc.add(NextZombieRound());
        add(zombieGenerateTimer!);
        if (bloc.state.zombieTimes >= bloc.state.zombiePeriods.length - 1) {
          zombiesTimer?.removeFromParent();
        }
      },
    );
    add(zombiesTimer!);
  }

  void readyForFight() {
    zombieGenerateTimer = null;
    SoundManager().initFightMusic(); // 音乐
    // 初始化草坪网格
    _initLawnGrid();
    // 生成僵尸
    _generateZombies();
    // 铲子
    _generateShovel();
  }

  // 生成铲子
  void _generateShovel() {
    add(ShovelComponent());
  }

  /// 将种植的位置 - 草坪
  LawnCell? findLawnCellFromPosition(Vector2 position) {
    LawnCell? lawnCell;
    try {
      lawnCell =
          lawnCells.firstWhere((cell) => cell.toRect().containsPoint(position));
      return lawnCell;
    } catch (_) {
      return lawnCell;
    }
  }

  @override
  void onPointerMove(PointerMoveEvent event) {
    updateShovelPosition(event);
    super.onPointerMove(event);
  }

  // 铲掉植物
  void removePlant() {
    selectShovel = false;
    final position = shovelDragShadow!.position + shovelDragShadow!.size / 2;
    LawnCell? lawnCell = findLawnCellFromPosition(position);
    lawnCell?.removePlant();
    remove(shovelDragShadow!);
    shovelDragShadow = null;
  }

  // 更新铲子的位置
  void updateShovelPosition(PointerMoveEvent event) {
    if (shovelDragShadow != null) {
      shovelDragShadow!.position =
          event.localPosition - shovelDragShadow!.size / 2;
    }
  }

  // 操作铲子
  void operateShove(Sprite shovel, Vector2 initPosition) {
    selectShovel = true;
    shovelDragShadow = DragShadow(
      shovel,
      setSize: Vector2(80, 80),
      paintColor: GameColors.shovelDragShadowColor,
    );
    shovelDragShadow?.position = initPosition;
    add(shovelDragShadow!);
  }
}
